home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-12-19 | 58.0 KB | 2,232 lines |
- Newsgroups: comp.sources.unix
- From: clyde@emx.utexas.edu (Clyde Hoover)
- Subject: v25i076: npasswd - replacement for passwd(1), Part03/03
- Sender: sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: clyde@emx.utexas.edu (Clyde Hoover)
- Posting-Number: Volume 25, Issue 76
- Archive-Name: npasswd/part03
-
- From clyde@emx.utexas.edu Fri Jan 25 12:45:55 1991
- Received: from BBN.COM by pineapple.bbn.com id <AA22526@pineapple.bbn.com>; Fri, 25 Jan 91 12:45:27 -0500
- Received: from uunet.UU.NET by BBN.COM id aa03197; 25 Jan 91 12:40 EST
- Received: from cs.utexas.edu by uunet.uu.net (5.61/1.14) with SMTP
- id AA17516; Fri, 25 Jan 91 12:39:43 -0500
- Received: from emx.utexas.edu by cs.utexas.edu (5.64/1.93) via SMTP
- id AA18063; Fri, 25 Jan 91 11:38:53 -0600
- Posted-Date: 25 Jan 91 17:04:17 GMT
- Received: by emx.utexas.edu (5.61/1.8)
- id AA09974; Fri, 25 Jan 91 11:04:20 -0600
- To: comp-sources-unix@emx.utexas.edu
- Path: ut-emx!clyde
- From: Head UNIX Hacquer <ut-emx!clyde@emx.utexas.edu>
- Newsgroups: comp.sources.unix
- Subject: npasswd, a replacement for passwd(1) (part 3 of 3)
- Keywords: Password changing program
- Message-Id: <43166@ut-emx.uucp>
- Date: 25 Jan 91 17:04:17 GMT
- Organization: Moose & Squirrel Software
- Lines: 2197
- Status: R
-
-
- Npasswd is a pretty-much-plug-compatable replacement for passwd(1).
- This version incorporates a password checking system
- that disallows simple-minded passwords.
-
- It does exactly ONE thing - change login passwords, though it would
- not be too difficult to make it do shells and GECOS stuff also.
-
- I have modeled npasswd after passwd(1) from 4.3BSD and SunOS 4.0, but
- it does not impliment the options those versions have.
- I have also included support for Sys VR3 password aging.
-
- This version runs at our site under SunOS 4.X, Ultrix 4.0, UMAX 4.3 and
- MORE/BSD.
-
- It is also available via anonymous FTP from emx.utexas.edu in the directory
- pub/npasswd.
-
- --------- cut here ----------
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 3)."
- # Contents: CHANGE.LOG checkpasswd/util.c npasswd.c pw_yp.c
- # Wrapped by clyde@tigger.cc.utexas.edu on Fri Jan 25 10:35:08 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'CHANGE.LOG' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'CHANGE.LOG'\"
- else
- echo shar: Extracting \"'CHANGE.LOG'\" \(9460 characters\)
- sed "s/^X//" >'CHANGE.LOG' <<'END_OF_FILE'
- X
- XSCCS/s.npasswd.1:
- X
- XD 1.3 90/08/14 14:45:58 clyde 3 2 00016/00006/00053
- XDocument -P flag
- X
- XD 1.2 89/09/21 14:31:45 clyde 2 1 00009/00016/00050
- XMisc changes
- X
- XD 1.1 89/05/18 10:25:49 clyde 1 0 00066/00000/00000
- Xdate and time created 89/05/18 10:25:49 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.npasswd.c:
- X
- XD 1.15 90/08/14 14:23:33 clyde 15 14 00099/00026/00471
- X1. Include <errno.h>
- X2. Add -P option (input via pipe from program).
- X3. Use #ifdefs for index() vs. strchr().
- X4. Change usage messages.
- X5. Don't prompt if input is from a pipe.
- X6. Print all status messages to stdout.
- X7. Terminate upon password entry/match error if stdin = pipe.
- X8. Exit messages to stdout if stdin = pipe.
- X9. Use 'cat' if stdin != tty.
- X10. Allow stdin to be tty or pipe (pipe only with -P option).
- X11. Add fgetpwent().
- X12. In putpwent(), type uid/gid as unsigned if UNSIGNED_UID defined.
- X
- XD 1.14 90/08/07 15:55:18 mic 14 13 00009/00004/00488
- XUse getpwuid() to get user id if getlogin() fails. This can happen if run
- Xfrom an rsh or by /bin/login before you are really logged in.
- X
- XD 1.13 90/06/05 11:07:10 clyde 13 12 00010/00003/00482
- XFix problem with overwriting password buffers
- X
- XD 1.12 90/01/16 16:21:38 clyde 12 11 00001/00001/00484
- XFix echo suppression for SunOS 4.0
- X
- XD 1.11 90/01/12 14:55:09 clyde 11 10 00006/00002/00478
- XBuild properly under SunOS 4.0
- X
- XD 1.10 89/11/15 14:17:19 clyde 10 9 00002/00001/00478
- XUpdate some comments
- X
- XD 1.9 89/11/01 16:21:29 clyde 9 8 00001/00000/00478
- XFix messge-of-the-day output
- X
- XD 1.8 89/09/27 10:27:17 clyde 8 7 00006/00004/00472
- XWork around syslogs with missing defines
- X
- XD 1.7 89/09/26 15:00:52 clyde 7 6 00015/00008/00461
- X1. Add 'message of the day' capability.
- X2. Change 'help()' to generalized 'motd()' routine.
- X
- XD 1.6 89/09/22 15:58:07 clyde 6 5 00033/00000/00436
- XInsert putpwent() and rename() [under #ifdef control]
- X
- XD 1.5 89/09/21 17:16:46 clyde 5 4 00004/00004/00432
- XChange occurances of 'npasswd' to 'passwd'
- X
- XD 1.4 89/09/21 17:08:49 clyde 4 3 00005/00004/00431
- XMove some stuff to static storage (bug workaround)
- X
- XD 1.3 89/06/28 14:20:36 clyde 3 2 00004/00000/00431
- XPut ifdefs around some configuration defines
- X
- XD 1.2 89/06/05 13:14:00 clyde 2 1 00056/00000/00375
- XAdd getpass() replacement routine (#ifdef XGETPASS)
- X
- XD 1.1 89/05/18 10:25:50 clyde 1 0 00375/00000/00000
- Xdate and time created 89/05/18 10:25:50 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.npasswd.cf:
- X
- XD 1.1 89/05/18 10:25:52 clyde 1 0 00020/00000/00000
- Xdate and time created 89/05/18 10:25:52 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.npasswd.hf:
- X
- XD 1.1 89/05/18 10:25:53 clyde 1 0 00005/00000/00000
- Xdate and time created 89/05/18 10:25:53 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.pw_passwd.c:
- X
- XD 1.8 90/08/07 16:01:00 root 8 7 00007/00005/00380
- XUse getpwuid() to get user id if getlogin() fails. This can happen if run
- Xfrom an rsh or by /bin/login before you are really logged in.
- X
- XD 1.7 90/07/23 09:37:18 clyde 7 6 00001/00001/00384
- XFix pw_compare()
- X
- XD 1.6 90/06/22 10:39:16 clyde 6 5 00002/00000/00383
- XMake password compare rtn deal with null password
- X
- XD 1.5 89/11/14 17:00:25 clyde 5 4 00005/00002/00378
- XDon't remove temp file unless I created it
- X
- XD 1.4 89/11/01 16:24:47 clyde 4 3 00003/00003/00377
- XChange DEBUG file names to './etc_XXXX'
- X
- XD 1.3 89/10/02 16:53:17 clyde 3 2 00018/00004/00362
- X1. Set file names with #define(s).
- X2. Set passwd file mode with a #define.
- X
- XD 1.2 89/09/22 15:57:24 clyde 2 1 00000/00033/00366
- XRemove putpwent() [moved to npasswd.c]
- X
- XD 1.1 89/05/18 10:25:54 clyde 1 0 00399/00000/00000
- Xdate and time created 89/05/18 10:25:54 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.pw_userinfo.c:
- X
- XD 1.4 90/08/07 15:56:31 mic 4 3 00008/00002/00248
- XUse getpwuid() to get user id if getlogin() fails. This can happen if run
- Xfrom an rsh or by /bin/login before you are really logged in.
- X
- XD 1.3 90/06/22 10:39:19 clyde 3 2 00002/00000/00248
- XMake password compare rtn deal with null password
- X
- XD 1.2 89/06/05 13:48:30 clyde 2 1 00172/00105/00076
- XFirst working version
- X
- XD 1.1 89/05/18 10:25:56 clyde 1 0 00181/00000/00000
- Xdate and time created 89/05/18 10:25:56 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.pw_yp.c:
- X
- XD 1.14 90/08/14 14:27:17 clyde 14 13 00056/00019/00558
- X1. Include filename in passwd open error messages.
- X2. Password history checking ifdef on PASSWORD_HISTORY.
- X3. Ignore passwd entries starting with YP special cookies.
- X4. Detect if local password is in adjunct passwd file.
- X5. Add newlines to all quit() messages.
- X6. Set real uid to effective uid before running YP update script.
- X7. Allow su to override YP ypdate script (env YP_UPDATE_PROC).
- X
- XD 1.13 90/08/07 16:01:01 root 13 12 00007/00005/00570
- XUse getpwuid() to get user id if getlogin() fails. This can happen if run
- Xfrom an rsh or by /bin/login before you are really logged in.
- X
- XD 1.12 90/06/22 10:39:13 clyde 12 11 00002/00000/00573
- XMake password compare rtn deal with null password
- X
- XD 1.11 90/05/29 14:41:29 clyde 11 10 00002/00001/00571
- XSet PATH before firing up YP make
- X
- XD 1.10 90/03/20 14:58:51 clyde 10 9 00003/00001/00569
- XMake sure passwd.ptmp is removed if /etc/ptmp create fails
- X
- XD 1.9 90/03/19 16:34:51 clyde 9 8 00009/00004/00561
- XPut secure RPC stuff in #ifdef SECURE_RPC
- X
- XD 1.8 90/03/19 16:09:27 clyde 8 7 00033/00014/00532
- X1. Split code that does locked temp files into routine.
- X2. If on YP master, create both "/etc/ptmp" and "PASSWD_FILE.ptmp".
- X
- XD 1.7 90/03/19 14:50:56 clyde 7 6 00154/00042/00392
- X1. Use direct syslog of errors where needed.
- X2. Add stub to call password history check.
- X3. Always encrypt password with new salt.
- X4. Use RPC calls directly for YP password change.
- X5. Add error checking and reporting for YP password changes.
- X6. Add stub for secure RPC key change.
- X7. Rewrite is_yp_master() to call YP routines instead of using ypwhich.
- X8. Add -DYPASSWDD_403 define to cope with SunOS 4.0.3 yppasswdd.
- X
- XD 1.6 89/11/14 17:00:39 clyde 6 5 00005/00002/00429
- XDon't remove temp file unless I created it
- X
- XD 1.5 89/11/01 16:24:41 clyde 5 4 00003/00003/00428
- XChange DEBUG file names to './etc_XXXX'
- X
- XD 1.4 89/10/02 16:52:59 clyde 4 3 00021/00004/00410
- X1. Set file names with #define(s).
- X2. Set passwd file mode with a #define.
- X
- XD 1.3 89/09/26 14:59:23 clyde 3 2 00040/00012/00374
- X1. Try yppasswd() call multiple times.
- X2. Move check for YP change capability from pw_replace() to pw_permission().
- X
- XD 1.2 89/05/19 11:01:35 clyde 2 1 00005/00001/00381
- XInstall PATH for exec of ypwhich
- X
- XD 1.1 89/05/18 10:25:57 clyde 1 0 00382/00000/00000
- Xdate and time created 89/05/18 10:25:57 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.version.h:
- X
- XD 1.5 90/08/14 14:37:26 clyde 5 4 00001/00001/00007
- XBump patch level
- X
- XD 1.4 90/03/19 13:58:10 clyde 4 3 00002/00002/00006
- XBump overall version to 1.2
- X
- XD 1.3 89/11/28 12:32:30 clyde 3 2 00002/00002/00006
- XUpdate version stamp
- X
- XD 1.2 89/09/21 17:25:54 clyde 2 1 00002/00002/00006
- XUpdate date info
- X
- XD 1.1 89/05/18 10:25:59 clyde 1 0 00008/00000/00000
- Xdate and time created 89/05/18 10:25:59 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.README:
- X
- XD 1.6 90/03/19 16:36:31 clyde 6 5 00002/00000/00129
- XAdd info about defining SECURE_RPC
- X
- XD 1.5 90/03/19 16:10:58 clyde 5 4 00000/00007/00129
- XRemove stuff about YPPASSWDD_403
- X
- XD 1.4 90/03/19 15:05:05 clyde 4 3 00015/00007/00121
- X1. Fix errors.
- X2. Explain configuring for SunOS 4.0.3
- X
- XD 1.3 89/11/28 12:24:45 clyde 3 2 00038/00004/00090
- XAdd sketch about the configuration file
- X
- XD 1.2 89/10/24 10:48:21 clyde 2 1 00001/00002/00093
- XRemove 'beta test' comment
- X
- XD 1.1 89/05/18 10:26:01 clyde 1 0 00095/00000/00000
- Xdate and time created 89/05/18 10:26:01 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.npasswd.help:
- X
- XD 1.1 89/09/21 14:20:53 clyde 1 0 00020/00000/00000
- Xdate and time created 89/09/21 14:20:53 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.Makefile.dist:
- X
- XD 1.8 90/07/23 09:59:01 clyde 8 7 00001/00001/00163
- XFix error in BSD build options
- X
- XD 1.7 89/12/05 09:37:18 clyde 7 6 00001/00001/00163
- XFix bug in install directives
- X
- XD 1.6 89/10/30 14:34:11 clyde 6 5 00006/00005/00158
- XAdd DEST to install lines to allow install in alternate fs tree
- X
- XD 1.5 89/10/24 11:17:43 clyde 5 4 00019/00012/00144
- X1. Add MANDIR for manual page install.
- X2. Change npasswd to $(PASSWD) except for source file references.
- X3. Don't replace config and help files if they already exist.
- X
- XD 1.4 89/10/04 09:54:42 clyde 4 3 00059/00016/00097
- XAdd commentary, massive other changes
- X
- XD 1.3 89/09/27 10:25:28 clyde 3 2 00014/00007/00099
- X1. Document -DXPUTPWENT flag.
- X2. Better paramaterization of file names.
- X
- XD 1.2 89/09/26 15:01:52 clyde 2 1 00007/00005/00099
- XAdd message-of-the-day file
- X
- XD 1.1 89/09/21 17:22:20 clyde 1 0 00104/00000/00000
- Xdate and time created 89/09/21 17:22:20 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- X
- XSCCS/s.passwd.1:
- X
- XD 1.1 89/10/24 10:51:25 clyde 1 0 00056/00000/00000
- Xdate and time created 89/10/24 10:51:25 by clyde
- X
- XUsers allowed to make deltas --
- X everyone
- X
- XFlags --
- X none
- X
- XDescription --
- X none
- END_OF_FILE
- if test 9460 -ne `wc -c <'CHANGE.LOG'`; then
- echo shar: \"'CHANGE.LOG'\" unpacked with wrong size!
- fi
- # end of 'CHANGE.LOG'
- fi
- if test -f 'checkpasswd/util.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'checkpasswd/util.c'\"
- else
- echo shar: Extracting \"'checkpasswd/util.c'\" \(11926 characters\)
- sed "s/^X//" >'checkpasswd/util.c' <<'END_OF_FILE'
- X
- X/* -------------------------------------------------------------------- */
- X/* */
- X/* Author: Clyde Hoover */
- X/* Computation Center */
- X/* The University of Texas at Austin */
- X/* Austin, Texas 78712 */
- X/* clyde@emx.utexas.edu */
- X/* uunet!cs.utexas.edu!ut-emx!clyde */
- X/* */
- X/*This code may be distributed freely, provided this notice is retained. */
- X/* */
- X/* -------------------------------------------------------------------- */
- X/*
- X * util.c - Miscellanous utility routines
- X */
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)util.c 1.4 11/14/89 (cc.utexas.edu)";
- X#endif
- X
- X#include "checkpasswd.h"
- X
- X/*
- X * _instring - Compare all sub-strings
- X *
- X * Returns:
- X * 0 if match not found
- X * rc if match found
- X */
- X_instring(s1, s2, rc)
- Xchar *s1, /* String to look for */
- X *s2; /* String to look for <s1> in */
- Xint rc; /* What to return on match */
- X{
- X int l; /* Temp */
- X
- X for (l = strlen(s1); *s2; s2++)
- X if (_cistrncmp(s1, s2, l) == 0)
- X return (rc);
- X return(0);
- X}
- X
- X/*
- X * _flipstring - reverse a string in place
- X */
- X_flipstring(s)
- Xchar *s; /* String to reverse */
- X{
- X char *p, /* Scratch */
- X *t; /* Scratch */
- X char *malloc();
- X
- X t = malloc(strlen(s) + 1);
- X (void) strcpy(t, s);
- X p = t;
- X while (*p) p++; /* Find end of string */
- X --p;
- X for (; *s; )
- X *s++ = *p--;
- X free(t);
- X}
- X
- X/*
- X * Case indepedant string comparasion routines swiped from
- X * the source to MIT Hesiod.
- X * Since these routines are publicly available,
- X * I presume to redistribute them is not in violation of copyright.
- X */
- X
- X/*
- X * Copyright (c) 1986 Regents of the University of California.
- X * All rights reserved. The Berkeley software License Agreement
- X * specifies the terms and conditions for redistribution.
- X */
- X
- X/*
- X * This array is designed for mapping upper and lower case letter
- X * together for a case independent comparison. The mappings are
- X * based upon ascii character sequences.
- X */
- Xstatic
- Xchar charmap[] = {
- X '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
- X '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
- X '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
- X '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
- X '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
- X '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
- X '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
- X '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
- X '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
- X '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
- X '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
- X '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
- X '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
- X '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
- X '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
- X '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
- X '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
- X '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
- X '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
- X '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
- X '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
- X '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
- X '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
- X '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
- X '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
- X '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
- X '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
- X '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
- X '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
- X '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
- X '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
- X '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
- X};
- X
- X/*
- X * cistrcmp - case independant string compare
- X */
- X_cistrcmp(s1, s2)
- Xregister char *s1, *s2;
- X{
- X register char *cm = charmap;
- X
- X while (cm[*s1] == cm[*s2++])
- X if (*s1++=='\0')
- X return(0);
- X return(cm[*s1] - cm[*--s2]);
- X}
- X
- X/*
- X * cistrncmp - case independant string compare
- X */
- X_cistrncmp(s1, s2, n)
- Xregister char *s1, *s2;
- Xregister n;
- X{
- X register char *cm = charmap;
- X
- X while (--n >= 0 && cm[*s1] == cm[*s2++])
- X if (*s1++ == '\0')
- X return(0);
- X return(n<0 ? 0 : cm[*s1] - cm[*--s2]);
- X}
- X/* end of UCB copyrighted code */
- X
- X/*
- X * _ctran - produce printable version of any ASCII character
- X */
- Xchar *
- X_ctran (c)
- Xchar c; /* Character to represent */
- X{
- X static char cbuf[8]; /* Return value buffer */
- X char *p = cbuf; /* Pointer to cbuf */
- X char chr = c & 0177; /* Scratch */
- X
- X if (c & 0200) { /* Meta char - weird but what the hey */
- X *p++ = 'M';
- X *p++ = '-';
- X }
- X if (chr >= ' ' && chr <= '~') {
- X *p++ = chr;
- X *p++ = 0;
- X return (cbuf);
- X }
- X if (chr == 0177)
- X return("DEL");
- X *p++ = '^';
- X *p++ = chr + '@';
- X *p++ = 0;
- X return (cbuf);
- X}
- X
- X/*
- X * The following routines are used by the configuration file processor.
- X */
- X
- X/*
- X * decode_boolean - decode a boolean value
- X */
- Xstatic
- Xdecode_boolean(s)
- Xchar *s;
- X{
- X return(*s == '1'
- X | streq(s, "true")
- X | streq(s, "yes")
- X | streq(s, "on"));
- X}
- X
- X/*
- X * decode_int - decode an integer value
- X */
- Xstatic
- Xdecode_int(s)
- Xchar *s; /* String to decode */
- X{
- X int t; /* Temp */
- X
- X if (xatoi(s, (char *)0, &t))
- X return(t);
- X fprintf(stderr, "Bad numeric value '%s'\n", s);
- X return(-1);
- X}
- X
- X/*
- X * Is argument an octal digit?
- X */
- Xstatic int octdigit(c)
- Xchar c;
- X{
- X return (c >= '0' && c <= '7');
- X}
- X
- X/*
- X * Is argument a decimal digit?
- X */
- Xstatic int decdigit(c)
- Xchar c;
- X{
- X return (c >= '0' && c <= '9');
- X}
- X
- X/*
- X * Is argument a hexidecimal digit?
- X */
- Xstatic int hexdigit(c)
- Xchar c;
- X{
- X return (decdigit(c) |
- X (c >= 'a' && c <= 'f') |
- X (c >= 'A' && c <= 'F'));
- X}
- X
- X/*
- X * xatoi - Smart 'atoi' recognizes decimal, octal and hex constants
- X */
- Xstatic
- Xxatoi(ip, ipp, iv)
- Xchar *ip, /* Pointer to number string */
- X **ipp; /* Stash pointer to end of string */ /* RETURN VALUE */
- Xint *iv; /* RETURN VALUE */
- X{
- X int (*func)() = decdigit, /* Function to check char */
- X base = 10; /* Conversion base */
- X int t = 0, /* Return value */
- X mult = 1; /* Sign of result */
- X char *fcc = ip; /* First char position */
- X
- X if (*ip == '-') { /* Negative number? */
- X ip++;
- X mult = -1;
- X }
- X if (*ip == '0') { /* Leading '0'? */
- X ip++;
- X if (*ip == 'x' || *ip == 'X') { /* Hex */
- X base = 16;
- X func = hexdigit;
- X ip++; /* Skip 'x' */
- X }
- X else {
- X base = 8; /* Octal */
- X func = octdigit;
- X }
- X }
- X while (*ip && (*func)(*ip)) {
- X t *= base;
- X if (decdigit(*ip))
- X t += (*ip - '0');
- X else
- X t += (*ip >= 'a' ? *ip - 0x57 : *ip - 0x37);
- X ip++;
- X }
- X if (ip == fcc) /* Nothing processed */
- X return(0);
- X if (ipp) /* Stash new pointer location */
- X *ipp = ip;
- X *iv = (t * mult);
- X return(1);
- X}
- X
- X/*
- X * decode_string - Copy string, converting backslash escapes
- X * Can handle most of the C backslash escape sequences
- X */
- Xstatic
- Xdecode_string(dst, src, len)
- Xchar *dst, /* Destination */
- X *src; /* Source */
- Xint len;
- X{
- X int t; /* Temp */
- X char *dstx = dst; /* Pointer to start of destination */
- X char quote = 0; /* Quote character */
- X
- X if (*src == '"' || *src == '\'')
- X quote = *src++;
- X
- X#define putxchar(P) *dst++ = (P)
- X for (; *src && (dst - dstx) < len; ) {
- X if (*src == '\\') {
- X src++;
- X switch(*src) {
- X case 'a': putxchar('\007'); src++; break;
- X case 'b': putxchar('\b'); src++; break;
- X case 'f': putxchar('\f'); src++; break;
- X case 'n': putxchar('\n'); src++; break;
- X case 'r': putxchar('\r'); src++; break;
- X case 't': putxchar('\t'); src++; break;
- X case '\\': putxchar('\\'); src++; break;
- X case '0': case '1': case '2': case '3':
- X case '4': case '5': case '6': case '7':
- X case 'x':
- X if (xatoi(src, &src, &t))
- X putxchar(t & 0xff);
- X break;
- X default:
- X if (quote && *src == quote)
- X *dst++ = *src++;
- X break;
- X }
- X continue;
- X }
- X else if (*src == '^') { /* ^C = control-c */
- X src++;
- X if (isupper(*src))
- X putxchar(*src - '@');
- X else if (islower(*src))
- X putxchar(*src - '`');
- X else switch (*src) {
- X case '[': putxchar('\033'); break;
- X case '\\': putxchar('\034'); break;
- X case ']': putxchar('\035'); break;
- X case '^': putxchar('\036'); break;
- X case '-': putxchar('\037'); break;
- X }
- X src++;
- X continue;
- X }
- X else if (quote && *src == quote)
- X break;
- X *dst++ = *src++;
- X }
- X#undef putxchar
- X *dst = 0;
- X}
- X
- Xstatic char *default_dicts[] = { /* List of default dictionaries */
- X#ifdef DEFAULT_DICT
- X DEFAULT_DICT,
- X#endif
- X 0
- X};
- X
- X/*
- X * readconfig - Read the configuration file
- X * Returns 1 if success, 0 if not found and -1 if error
- X */
- Xreadconfig(filename)
- Xchar *filename;
- X{
- X char buf[BUFSIZ]; /* Read buffer */
- X FILE *fp; /* File pointer */
- X char **p; /* Scratch */
- X int lineno = 0; /* Current line number in config file */
- X extern int standalone; /* Am I a standalone application? */
- X
- X /* "Load" default directories */
- X for (p = default_dicts; *p; p++)
- X add_dict(*p);
- X
- X if ((fp = fopen(filename, "r")) == NULL) {
- X#ifdef DEBUG
- X printf("No config file\n");
- X#endif
- X return(0);
- X }
- X
- X while (fgets(buf, sizeof(buf), fp) != NULL) {
- X char *key, /* Key on line */
- X *data; /* Data on line */
- X
- X lineno++;
- X if (buf[0] == '\n') /* Empty line */
- X continue;
- X if (key = index(buf, '\n'))
- X *key = 0;
- X for (data = buf; *data && *data <= ' '; data++);
- X if (*data == '#')
- X continue;
- X key = data;
- X for (; *data && *data > ' '; data++); /* Skip to end */
- X if (*data)
- X *data++ = 0;
- X else {
- X if (standalone)
- X printf("\"%s\", line %d: Incomplete line.\n",
- X filename, lineno);
- X continue;
- X }
- X for (; *data && *data <= ' '; data++); /* Skip whitespace */
- X if (streq(key, "dictionary"))
- X add_dict(data);
- X else if (streq(key, "singlecase"))
- X single_case = decode_boolean(data);
- X else if (streq(key, "minlength"))
- X min_length = decode_int(data);
- X else if (streq(key, "maxlength"))
- X max_length = decode_int(data);
- X else if (streq(key, "printonly"))
- X print_only = decode_boolean(data);
- X else if (streq(key, "badchars")) {
- X char xcc[BUFSIZ];
- X char append = 0;
- X
- X if (*data == '+') /* Add data to existing list */
- X append = *data++;
- X decode_string(xcc, data, BUFSIZ);
- X if (xcc[0] == 0)
- X continue;
- X if (append)
- X (void) strcat(illegalcc, xcc);
- X else
- X (void) strncpy(illegalcc, xcc, sizeof_illegalcc);
- X }
- X else {
- X if (standalone)
- X printf("\"%s\", line %d: Unrecognized keyword '%s'.\n",
- X filename, lineno, key);
- X }
- X }
- X (void) fclose(fp);
- X return(1);
- X}
- X
- X/*
- X * add_dict - Add a dictionary to the search list
- X *
- X * Arguments:
- X * The rest of the line from the configuration file
- X * which contains the path to the dictionary and optionally
- X * a descriptive phrase
- X */
- Xstatic
- Xadd_dict(line)
- Xchar *line; /* RHS of config line */
- X{
- X dictionary *dx, /* Tail of directory list */
- X *dn; /* New entry */
- X char *tx, /* Scratch */
- X *p; /* Scratch */
- X char *calloc();
- X
- X#ifdef DEBUG
- X printf("Add dictionary '%s'\n", line);
- X#endif
- X dn = (dictionary *)calloc(sizeof(dictionary), 1);
- X if (dictionaries == 0)
- X dictionaries = dn;
- X
- X for (dx = dictionaries; dx->dict_next ; dx = dx->dict_next);
- X
- X tx = malloc(strlen(line) + 1);
- X (void) strcpy(tx, line);
- X p = tx;
- X while (*p && *p > ' ') p++;
- X if (*p)
- X *p++ = 0;
- X dn->dict_path = tx;
- X dn->dict_desc = p;
- X dx->dict_next = dn;
- X dn->dict_next = 0;
- X}
- X/* End util.c */
- END_OF_FILE
- if test 11926 -ne `wc -c <'checkpasswd/util.c'`; then
- echo shar: \"'checkpasswd/util.c'\" unpacked with wrong size!
- fi
- # end of 'checkpasswd/util.c'
- fi
- if test -f 'npasswd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'npasswd.c'\"
- else
- echo shar: Extracting \"'npasswd.c'\" \(15199 characters\)
- sed "s/^X//" >'npasswd.c' <<'END_OF_FILE'
- X
- X/* -------------------------------------------------------------------- */
- X/* */
- X/* Author: Clyde Hoover */
- X/* Computation Center */
- X/* The University of Texas at Austin */
- X/* Austin, Texas 78712 */
- X/* clyde@emx.utexas.edu */
- X/* uunet!cs.utexas.edu!ut-emx!clyde */
- X/* */
- X/*This code may be distributed freely, provided this notice is retained. */
- X/* */
- X/* -------------------------------------------------------------------- */
- X/*
- X * This program duplicates the manual page behavior of the 4.XBSD
- X * passwd(1) command. It can be configured for use with a variety
- X * of passwd systems (/etc/passwd, /etc/shadow, databases).
- X *
- X * The System V support is untested (by the author - other sites
- X * tell me it works).
- X *
- X * Here we have only the most abstract data needed (login name,
- X * user id, current password, new password).
- X * All other information needed (the full password line, etc),
- X * is kept down in the 'method' routines.
- X *
- X * The 'method' routines are:
- X *
- X * pw_initalize() Do initializations
- X * pw_getuserbyname() Get user information by name
- X * pw_permission() Check if user has permission
- X * to change this users' password
- X * pw_compare() Compare passwords
- X * pw_check() Check password
- X * Returns 1 if ok, 0 otherwise
- X * pw_replace() Replace the password
- X * pw_cleanup() Cleanup
- X */
- X#ifdef SYSLOG
- X#include <syslog.h>
- X# ifndef LOG_AUTH
- X# define LOG_AUTH 0
- X# endif
- X# ifndef LOG_CONS
- X# define LOG_CONS 0
- X# endif
- X#endif
- X
- X#include <ctype.h>
- X#include <signal.h>
- X#include <sys/types.h>
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <errno.h>
- X#include "version.h"
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)npasswd.c 1.16 9/24/90 (cc.utexas.edu) /usr/share/src/private/ut/share/bin/passwd/SCCS/s.npasswd.c";
- X#endif
- X
- X#ifndef CONFIG_FILE
- X#define CONFIG_FILE "/usr/adm/passwd.conf"
- X#endif
- X#ifndef HELP_FILE
- X#define HELP_FILE "/usr/adm/passwd.help"
- X#endif
- X#ifndef MOTD_FILE
- X#define MOTD_FILE "/usr/adm/passwd.motd"
- X#endif
- X
- Xextern int errno; /* System error code */
- X
- X#ifdef sun
- Xstatic char *options = "alyd:e:F:n:fPsVx:"; /* Command line options */
- X#else
- Xstatic char *options = "fPsV"; /* Command line options */
- X#endif
- Xstatic int retries = 3; /* Retry limit */
- Xstatic int from_prog = 0; /* Data source is a program */
- X
- Xstatic char username[16], /* Name of user changing password */
- X password[16]; /* Current password (encrypted) */
- X
- Xchar pbuf[16], /* Password read buffer 1 */
- X pbuf2[16], /* Password read buffer 2 */
- X ppbuf[16], /* Current password */
- X mylogin[16]; /* My login name (saved) */
- X
- Xchar *getpass(),
- X *malloc(),
- X *ttyname(),
- X *getlogin();
- X
- X#ifdef SYSV
- X#define index strchr
- X#endif
- Xchar *index();
- X
- Xint catchit(); /* Signal catcher */
- X
- X/*
- X * passwd - change the password for a user.
- X *
- X * This program impliments the 'passwd' command.
- X */
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X char *myname, mysavedname[16];/* My login name */
- X struct passwd *pw; /* My passwd entry */
- X int opt; /* Option processing temp */
- X extern char *optarg; /* From getopt() */
- X extern int optind; /* From getopt() */
- X
- X /*
- X * Handle the 4.3BSD & SunOS 4.0 command line options.
- X * Defer everything except password change to other programs.
- X */
- X while ((opt = getopt(argc, argv, options)) != EOF) {
- X switch (opt) {
- X#ifdef sun
- X /*
- X * Recognized the SunOS 4.1 switches
- X * but just say that we don't handle them.
- X */
- X case 'a':
- X printf("Option \"-a\" not supported.\n");
- X exit(1);
- X case 'l':
- X printf("Option \"-l\" not supported.\n");
- X exit(1);
- X case 'y':
- X printf("Option \"-y\" not supported.\n");
- X exit(1);
- X case 'd':
- X printf("Option \"-d\" not supported.\n");
- X exit(1);
- X case 'e':
- X printf("Option \"-e\" not supported.\n");
- X exit(1);
- X case 'n':
- X printf("Option \"-n\" not supported.\n");
- X exit(1);
- X case 'x':
- X printf("Option \"-x\" not supported.\n");
- X exit(1);
- X case 'F':
- X printf("Option \"-F\" not supported.\n");
- X exit(1);
- X#endif
- X case 'f':
- X punt("chfn");
- X break;
- X case 's':
- X punt("chsh");
- X break;
- X case 'P': /* Data source is a program */
- X if (getuid())
- X quit(0, "Option \"-P\" reserved for super-user.\n");
- X from_prog = 1;
- X break;
- X case 'V':
- X printf("%s; patch level %s\n", version, patchlevel);
- X exit(0);
- X }
- X }
- X bzero(ppbuf, sizeof(ppbuf));
- X#ifndef DEBUG
- X if (geteuid())
- X quit(0,"Permission denied.\n");
- X#endif
- X checktty();
- X savetty();
- X myname = getlogin();
- X if (myname == 0 || *myname == '\0') {
- X if ((pw = getpwuid(getuid())) == ((struct passwd *)NULL))
- X quit(1, "Cannot get your login name.\n");
- X strncpy(mysavedname, pw->pw_name, sizeof(mysavedname));
- X myname = mysavedname;
- X }
- X (void) strcpy(mylogin, myname);
- X (void) signal(SIGINT, catchit);
- X (void) signal(SIGQUIT, catchit);
- X
- X#ifdef SYSLOG
- X openlog("passwd", LOG_PID | LOG_CONS, LOG_AUTH);
- X#endif
- X setcheckpasswd("-c", CONFIG_FILE, 0);
- X pw_initialize();
- X
- X if (argv[optind])
- X (void) strcpy(username, argv[optind]);
- X else
- X (void) strcpy(username, mylogin);
- X
- X if (strcmp(username, mylogin) == 0 && getuid()) {
- X if (pw_getuserbyname(username, password) == 0)
- X quit(1, "Cannot get your password information.\n");
- X if (password[0])
- X getpassword(password, ppbuf, sizeof(ppbuf));
- X }
- X else {
- X if (pw_getuserbyname(username, password) == 0)
- X quit(0, "No such user %s\n", argv[optind]);
- X if (pw_permission() == 0)
- X quit(0, "Permission denied.\n");
- X printf("Changing password for %s\n", username);
- X }
- X motd(MOTD_FILE, (char *)0);
- X
- X for (;;) {
- X char *px; /* Temp */
- X int ntries = 0; /* Password match counter */
- X
- X px = getpass(from_prog ? "" : "New password (? for help): ");
- X if (px == NULL)
- X quit(0, "EOF during new password read.\n");
- X (void) strcpy(pbuf, px);
- X if (pbuf[0] == '?') {
- X motd(HELP_FILE, "Missing help file");
- X continue;
- X }
- X /* Sanity check the new password */
- X if (pw_check(pbuf) == 0)
- X continue;
- X
- X /* Get confirmation */
- X px = getpass(from_prog ? "" : "New password (again): ");
- X if (px == NULL)
- X quit(0, "EOF during new password read.\n");
- X (void) strcpy(pbuf2, px);
- X if (strcmp(pbuf, pbuf2)) {
- X if (ntries++ >= retries)
- X quit(0, "Too many attempts.\n");
- X else
- X printf("They don't match; try again.\n");
- X if (from_prog)
- X quit(0, (char *)0);
- X else
- X continue;
- X }
- X /* Disallow new password == old password */
- X if (pw_compare(password, pbuf)) {
- X printf("New password must be different than old; try again.\n");
- X if (from_prog)
- X quit(0, (char *)0);
- X else
- X continue;
- X }
- X else
- X break;
- X }
- X pw_replace(pbuf, ppbuf);
- X#ifdef SYSLOG
- X syslog(LOG_INFO, "Password changed for %s by %s\n",
- X username, mylogin);
- X#endif
- X printf("Password changed for %s\n", username);
- X pw_cleanup(0);
- X exit(0);
- X}
- X
- X
- X/*
- X * getpassword -- read password and check against current.
- X */
- Xgetpassword(pwd_crypt, pwd_plain, pwlen)
- Xchar *pwd_crypt, /* Present password (encrypted) */
- X *pwd_plain; /* Present password (plain) */
- Xint pwlen; /* Length of present password buffer */
- X{
- X int ntries = 0; /* Match attempt counter */
- X char *px; /* Temp */
- X
- X for (;;) {
- X px = getpass(from_prog ? "" : "Current password: ");
- X if (px == 0)
- X quit(0, "EOF during password read.\n");
- X if (*px == '\0')
- X continue;
- X if (!pw_compare(pwd_crypt, px)) {
- X printf("Password incorrect.\n");
- X if (ntries++ == retries)
- X quit(0, "Password not matched.\n");
- X }
- X else
- X break;
- X }
- X if (pwd_plain)
- X (void) strncpy(pwd_plain, px, pwlen);
- X}
- X
- X/*
- X * randomstring - create a string of random characters
- X */
- Xrandomstring(buf, len)
- Xchar buf[]; /* String buffer */
- Xint len; /* Length of buf */
- X{
- X register int i, /* Temp */
- X n; /* Temp */
- X time_t tv; /* Current time */
- X char proto[128]; /* Build buffer */
- X
- X (void) time (&tv);
- X /*
- X * Assumes (implicitly) that sizeof(int) == sizeof(long)
- X */
- X (void) srand ( (tv & 0x38d9fcff) ^ getpid ());
- X for (i = 0; i < sizeof(proto); i++) { /* fill proto vector */
- X int c; /* Temp */
- X
- X for (;;) {
- X c = rand () % 0x7f; /* turn into ASCII */
- X if (isalnum (c))
- X break;
- X }
- X proto[i] = (char )c;
- X }
- X (void) srand(((unsigned )tv & 0x1a90fefc) ^ getpid());
- X for (i = 0; i < len; i++) {
- X n = rand() % sizeof(proto);
- X buf[i] = proto[n];
- X }
- X buf[len] = 0;
- X}
- X
- X/*
- X * quit - print/log error message and exit
- X */
- Xquit(logit, message, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
- X/*VARARGS2*/
- Xint logit; /* 0 = don't log, <> 0 = log message */
- Xchar *message; /* Message */
- Xint *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9, *a10; /* Args */
- X{
- X if (message) {
- X /*
- X * If used from program, direct failure messages to stdout,
- X * else send to stderr.
- X */
- X fprintf(from_prog ? stdout : stderr, message,
- X a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
- X#ifdef SYSLOG
- X if (logit)
- X syslog(LOG_ERR, message,
- X a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
- X#endif
- X }
- X pw_cleanup(1);
- X exit(1);
- X}
- X
- X/*
- X * motd - issue 'message of the day'
- X */
- Xmotd(fn, complaint)
- Xchar *fn, /* Name of file to present */
- X *complaint; /* Complaint if missing */
- X{
- X char cmdbuf[BUFSIZ]; /* Buffer to build command in */
- X
- X if (access(fn, 0) < 0) {
- X if (complaint)
- X printf("%s\n", complaint);
- X return;
- X }
- X if (isatty(0))
- X#ifdef SYSV
- X (void) sprintf(cmdbuf, "pg -n -s %s", fn);
- X#else
- X (void) sprintf(cmdbuf, "more -d %s", fn);
- X#endif
- X else
- X (void) sprintf(cmdbuf, "cat %s", fn);
- X
- X if (fork() == 0) {
- X (void) setgid(getgid());
- X (void) setuid(getuid());
- X (void) system(cmdbuf);
- X exit(0);
- X }
- X (void) wait((int *)0); /* "Wrong" for BSD, right for SYS V */
- X}
- X
- X/*
- X * checktty - Attempt to check against being pipe-fed
- X */
- Xchecktty()
- X{
- X char *stdin_tty, /* ttyname(0) */
- X *stdout_tty, /* ttyname(1) */
- X *t; /* Temp */
- X
- X if (!isatty(0)) {
- X if (from_prog == 0)
- X quit(0, "Input not a tty.\n");
- X if (lseek(0, 0L, 1) < 0) {
- X if (errno != ESPIPE)
- X quit(0, "Input not a tty or pipe.\n");
- X else
- X return;
- X }
- X }
- X from_prog = 0; /* Stdin is a tty - behave normal */
- X stdin_tty = ttyname(0);
- X if (stdin_tty == NULL || *stdin_tty == 0)
- X quit(0, "Cannot get name (stdin).\n");
- X t = malloc(strlen(stdin_tty) + 1);
- X if (t == NULL)
- X quit(1, "Cannot allocate temp memory.");
- X (void) strcpy(t, stdin_tty);
- X stdin_tty = t;
- X
- X stdout_tty = ttyname(1);
- X if (stdout_tty == NULL || *stdout_tty == 0)
- X quit(0, "Cannot get name (stdout).\n");
- X if (strcmp(stdin_tty, stdout_tty))
- X quit(0, "Input and output are not the same tty.\n");
- X free(stdin_tty);
- X}
- X
- X/*
- X * catchit - tty interrupt catcher
- X */
- Xcatchit()
- X{
- X fixtty();
- X pw_cleanup(1);
- X quit(0, "\nInterrupted; changes discarded.\n");
- X}
- X
- X
- X#if defined(SYSV)
- X# include <termio.h> /* Vanilla SV termio */
- X struct termio saved_tty_mode;
- X#endif
- X
- X#if defined(SUNOS4)
- X# include <sys/termios.h> /* SUN OS 4.0 termio */
- X#define TCGETA TCGETS
- X#define TCSETA TCSETS
- X struct termios saved_tty_mode;
- X#endif
- X
- X#if !defined(SUNOS4) && !defined(SYSV)
- X# include <sgtty.h> /* BSD tty */
- X struct sgttyb saved_tty_mode;
- X int saved_local_flags;
- X#endif
- Xchar saves_valid = 0; /* Are the saved values valid? */
- X
- X/*
- X * savetty - save current terminal settings
- X */
- Xsavetty()
- X{
- X#if defined(SYSV) || defined(SUNOS4)
- X (void) ioctl(0, TCGETA, &saved_tty_mode);
- X#else
- X (void) ioctl(0, TIOCGETP, &saved_tty_mode);
- X (void) ioctl(0, TIOCLGET, &saved_local_flags);
- X#endif
- X saves_valid++;
- X}
- X
- X/*
- X * fixtty - restore saved terminal settings
- X */
- Xfixtty()
- X{
- X if (saves_valid) {
- X#if defined(SYSV) || defined(SUNOS4)
- X (void) ioctl(0, TCSETA, &saved_tty_mode);
- X#else
- X (void) ioctl(0, TIOCSETP, &saved_tty_mode);
- X (void) ioctl(0, TIOCLSET, &saved_local_flags);
- X#endif
- X }
- X}
- X
- X#ifdef XGETPASS
- X/*
- X * The system getpass() throws away all but the first 8 characters
- X * of a password string. If this isn't enough for you, use this
- X * routine instead. This code assumes that stdin is the terminal.
- X */
- Xchar *
- Xgetpass(prompt)
- Xchar *prompt;
- X{
- X#if defined(SYSV)
- X struct termio saved, /* Saved tty characteristics */
- X noecho; /* No-echo tty characteristics */
- X char *strchr();
- X#endif
- X#if defined(SUNOS4)
- X struct termios saved, /* Saved tty characteristics */
- X noecho; /* No-echo tty characteristics */
- X#else
- X struct sgttyb saved, /* Saved tty characteristics */
- X noecho; /* No-echo tty characteristics */
- X#endif
- X static char ib[64]; /* Input buffer */
- X char *rc; /* Temp */
- X
- X#if defined(SYSV) || defined(SUNOS4)
- X (void) ioctl(0, TCGETA, &saved);
- X noecho = saved;
- X noecho.c_lflag &= ~ECHO;
- X (void) ioctl(0, TCSETA, &noecho);
- X#else
- X (void) ioctl(0, TIOCGETP, &saved);
- X noecho = saved;
- X noecho.sg_flags &= ~ECHO;
- X (void) ioctl(0, TIOCSETP, &noecho);
- X#endif
- X fprintf(stderr, "%s", prompt);
- X fflush(stderr);
- X rc = fgets(ib, sizeof(ib), stdin);
- X putc('\n', stderr);
- X fflush(stderr);
- X
- X#if defined(SYSV) || defined(SUNOS4)
- X (void) ioctl(0, TCSETA, &saved);
- X#else
- X (void) ioctl(0, TIOCSETP, &saved);
- X#endif
- X if (rc == NULL)
- X return(NULL);
- X if (rc = index(ib, '\n'))
- X *rc = 0;
- X return(ib);
- X}
- X#endif
- X
- X#ifdef XPUTPWENT
- X/*
- X * putpwent - replacement for the System V routine
- X * This writes the "standard" passwd file format.
- X */
- Xputpwent(p, f)
- Xstruct passwd *p; /* Passwd entry to put */
- XFILE *f; /* File pointer */
- X{
- X#ifdef UNSIGNED_UID
- X fprintf(f, "%s:%s:%u:%u:%s:%s:%s\n",
- X#else
- X fprintf(f, "%s:%s:%d:%d:%s:%s:%s\n",
- X#endif
- X p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid,
- X p->pw_gecos, p->pw_dir, p->pw_shell);
- X}
- X#endif
- X
- X#ifdef XFGETPWENT
- X/*
- X * fgetpwent() - read passwd(5) entry from a file
- X * This reads the "standard" passwd file format.
- X */
- Xstruct passwd *
- Xfgetpwent(f)
- XFILE *f; /* Pointer to open passwd format file */
- X{
- X static struct passwd pwdata; /* Return data */
- X static char ibuf[BUFSIZ]; /* Input and return data buffer */
- X char *p; /* ACME Pointer Works, Inc */
- X
- X bzero((char *)&pwdata, sizeof(pwdata));
- X pwdata.pw_name = pwdata.pw_passwd = pwdata.pw_comment =
- X pwdata.pw_gecos = pwdata.pw_dir = pwdata.pw_shell = "";
- X
- X if (fgets(ibuf, sizeof(ibuf), f) == NULL)
- X return(0);
- X if ((p = index(ibuf, '\n')) == 0) /* Zap newline */
- X quit(1, "Ill-formed passwd entry \"%s\".\n", ibuf);
- X else
- X *p = 0;
- X#define skipc while (*p && *p != ':' && *p != '\n') ++p; if (*p) *p++ = 0
- X p = ibuf;
- X pwdata.pw_name = p; skipc;
- X pwdata.pw_passwd = p; skipc;
- X pwdata.pw_uid = atoi(p); skipc;
- X pwdata.pw_gid = atoi(p); skipc;
- X pwdata.pw_gecos = p; skipc;
- X pwdata.pw_dir = p; skipc;
- X pwdata.pw_shell = p;
- X return(&pwdata);
- X#undef skipc
- X}
- X#endif
- X
- X#ifdef SYSV
- X/*
- X * rename - replacement for the 4.2/4.3 BSD rename system call
- X */
- Xrename(src, dst)
- Xchar *src, /* Source path */
- X *dst; /* Destination path */
- X{
- X if (unlink(dst) < 0) {
- X if (errno != ENOENT)
- X return(-1);
- X }
- X if (link(src, dst) < 0)
- X return(-1);
- X return(unlink(src));
- X}
- X#endif
- X
- X/*
- X * punt() - run another program to do what we don't do
- X */
- Xpunt(prog)
- Xchar *prog; /* Program to run */
- X{
- X (void) setgid(getgid());
- X (void) setuid(getuid());
- X (void) execlp(prog, prog, 0);
- X perror(prog);
- X exit(1);
- X}
- X/* End npasswd.c */
- END_OF_FILE
- if test 15199 -ne `wc -c <'npasswd.c'`; then
- echo shar: \"'npasswd.c'\" unpacked with wrong size!
- fi
- # end of 'npasswd.c'
- fi
- if test -f 'pw_yp.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pw_yp.c'\"
- else
- echo shar: Extracting \"'pw_yp.c'\" \(16110 characters\)
- sed "s/^X//" >'pw_yp.c' <<'END_OF_FILE'
- X
- X/* -------------------------------------------------------------------- */
- X/* */
- X/* Author: Clyde Hoover */
- X/* Computation Center */
- X/* The University of Texas at Austin */
- X/* Austin, Texas 78712 */
- X/* clyde@emx.utexas.edu */
- X/* uunet!cs.utexas.edu!ut-emx!clyde */
- X/* */
- X/*This code may be distributed freely, provided this notice is retained. */
- X/* */
- X/* -------------------------------------------------------------------- */
- X/*
- X * pw_yp - Routines for dealing with SUN Yellow Pages password files
- X *
- X * This code can update local password file, can cause rebuilding of
- X * local YP maps and can use yppasswdd(8) to change YP passwords.
- X *
- X * Must be linked with -lrpcsvc
- X */
- X#include <stdio.h>
- X#include <sys/param.h>
- X#include <sys/stat.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include <pwd.h>
- X#include <fcntl.h>
- X#include <rpc/rpc.h>
- X#include <rpcsvc/ypclnt.h>
- X#include <rpcsvc/yppasswd.h>
- X#include <sys/socket.h>
- X
- X#ifdef SECURE_RPC
- X#include <rpc/key_prot.h>
- X#endif
- X
- X#ifdef SYSV
- X#define index strchr
- X#endif
- X
- X#ifdef SYSLOG
- X#include <syslog.h>
- X#endif
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)pw_yp.c 1.15 1/25/91 (cc.utexas.edu)";
- X#endif
- X
- X#define NONE -1 /* YP not active */
- X#define NOT 0 /* YP active - we are not master */
- X#define IS 1 /* YP active - we have the password file */
- X
- X#define SLOP 128 /* Size difference tolerated old <> new passwd file */
- X
- Xtypedef struct passwd passwd;
- Xtypedef struct passwd *passwdp;
- X
- Xstatic passwd theUser, /* User being changed */
- X Me; /* User invoking passwd */
- Xstatic int myuid, /* Uid of invoker */
- X mytempfile = 0; /* Does PASSWD_TEMP belong to me? */
- Xstatic char *ypmaster, /* Name of the YP master */
- X *ypdomain; /* YP domain name */
- X
- X#define PASSWD_MAP "passwd.byname" /* Name of YP passwd map */
- X
- X/*
- X * File names
- X */
- X#ifndef PASSWD_FILE
- X#define PASSWD_FILE "/etc/passwd"
- X#endif
- X
- X#ifndef PASSWD_SAVE
- X#define PASSWD_SAVE "/etc/opasswd"
- X#endif
- X
- X#ifndef PASSWD_TEMP
- X#define PASSWD_TEMP "/etc/ptmp"
- X#endif
- X
- X#define PASSWD_MODE 0644
- X
- X#ifdef DEBUG
- Xstatic char *passwdtemp = "./etc_ptmp", /* Temp file */
- X *passwdfile = "./etc_passwd", /* Password file */
- X *savefile = "./etc_opasswd"; /* Save file */
- X#else
- Xstatic char *passwdtemp = PASSWD_TEMP,
- X *passwdfile = PASSWD_FILE,
- X *savefile = PASSWD_SAVE;
- X#endif
- Xstatic char auxlockfile[MAXPATHLEN]; /* Aux lock file */
- X
- Xextern int errno;
- X
- Xchar *getlogin(),
- X *crypt();
- X
- X/*
- X * pw_initialize - set up
- X */
- Xpw_initialize()
- X{
- X passwdp me; /* Passwd for invoker */
- X char *myname = getlogin(); /* Invoker login name */
- X
- X#ifdef DEBUG
- X setpwfile(passwdfile);
- X#endif
- X myuid = getuid();
- X if (myname && *myname) {
- X if ((me = getpwnam(myname)) == NULL)
- X quit(1, "Cannot get user identification from name.\n");
- X } else {
- X if ((me = getpwuid(myuid)) == NULL)
- X quit(1, "Cannot get user identification from uid.\n");
- X }
- X
- X _cppasswd(me, &Me);
- X return(1);
- X}
- X
- X/*
- X * pw_getuserbyname - get password
- X *
- X * Returns 1 if passwd found for <name>
- X * 0 otherwise
- X */
- Xpw_getuserbyname(name, passwdb)
- Xchar *name, /* User name */
- X *passwdb; /* Where to stuff password */
- X{
- X passwdp p; /* Temp */
- X
- X if ((p = getpwnam(name)) == NULL)
- X return(0);
- X _cppasswd(p, &theUser);
- X (void) strcpy(passwdb, p->pw_passwd);
- X return(1);
- X}
- X
- X/*
- X * pw_permission - check password change permission
- X *
- X * Returns 1 if password can be changed
- X * 0 if not
- X */
- Xpw_permission()
- X{
- X /*
- X * Is this my password or someone elses?
- X */
- X if (strcmp(Me.pw_name, theUser.pw_name) && myuid)
- X return(0);
- X
- X /*
- X * If on a YP client, root cannot change another
- X * users' password via yppasswd(), since we can't
- X * get a plain text password to pass to yppasswdd().
- X */
- X if (myuid == 0 && is_yp_master() == NOT) {
- X FILE *pf;
- X passwdp px, /* Password file traversal */
- X fgetpwent();
- X int rc = 0;
- X
- X /* What if passwdfile != /etc/passwd? */
- X if ((pf = fopen(passwdfile, "r")) == NULL)
- X quit(1, "Cannot open password file \"%s\".\n", passwdfile);
- X /*
- X * Scan local password file, looking for user
- X * Cannot use getpwnam() because it will use YP - I want to know
- X * if the user's password file entry is >>local<<
- X */
- X while ((px = fgetpwent(pf)) != NULL) {
- X if (strcmp(px->pw_name, theUser.pw_name) == 0) {
- X rc = 1;
- X break;
- X }
- X }
- X fclose(pf);
- X if (rc) {
- X if (strncmp(px->pw_passwd, "##", 2) == 0)
- X quit(0,
- X "Changing of adjunct passwords not supported.\n");
- X return(1);
- X }
- X else
- X quit(0, "Password for %s can only be changed on YP server %s.\n",
- X theUser.pw_name, ypmaster);
- X }
- X /* Check if passwd is '##username' - can't do that yet */
- X
- X /*
- X * Other checks can be put here to determine if the invoker should
- X * be allowed to change this password.
- X */
- X return(1);
- X}
- X
- X/*
- X * pw_compare - compare old and new passwords
- X *
- X * Returns 1 if check = new, 0 if not
- X */
- Xpw_compare(current, new)
- Xchar *current, /* Current pw (encrypted) */
- X *new; /* check pw (plain) */
- X{
- X if (!*current) /* Is current password null? */
- X return(0);
- X /* Put other administrative checks here */
- X return(!strcmp(current, crypt(new, current)));
- X}
- X
- X/*
- X * pw_check - sanity check password. Right now just calls
- X * the password check code
- X *
- X * Returns 1 if password is ok to use, 0 otherwise
- X */
- Xpw_check(pwd)
- Xchar *pwd;
- X{
- X int rc = checkpasswd(theUser.pw_uid, pwd);
- X
- X#ifdef PASSWORD_HISTORY
- X if (rc)
- X return(rc);
- X /* Call password history checker to prevent password reuse */
- X rc = passwd_history(theUser.pw_uid, pwd);
- X#endif
- X return(rc);
- X}
- X
- X/* Error message for when yppasswdd fails with error code 1. */
- Xstatic char *yperrmsg =
- X"Password change failed: Problem with yppasswdd.\n\n\
- XThis is probably because the YP maps are out of sync\n\
- Xwith the YP passwd file for %s on %s.\n\n\
- XPlease try again later.\n";
- X
- X/*
- X * pw_replace - replace password in passwd file
- X */
- Xpw_replace(newpwd, curpwd)
- Xchar *newpwd, /* New password (plain) */
- X *curpwd; /* Old password (plain) */
- X{
- X passwdp px, /* Password file traversal */
- X fgetpwent();
- X long oldsigs, /* Old signal mask */
- X blocksigs = sigmask(SIGINT) | /* Sigs to block */
- X sigmask(SIGQUIT) |
- X sigmask(SIGTSTP);
- X FILE *tf, /* New password file output */
- X *pf; /* Current password file input */
- X int fd, /* Temp file create fd */
- X islocal = 0; /* Is user in local password file */
- X struct stat oldstat, /* Old password file stat */
- X newstat; /* New password file stat */
- X
- X if ((pf = fopen(passwdfile, "r")) == NULL)
- X quit(1, "Cannot open password file \"%s\".\n", passwdfile);
- X /*
- X * Scan local password file, looking for user
- X * Cannot use getpwnam() because it will use YP - I want to know
- X * if I have to change a >>local<< password file.
- X */
- X while ((px = fgetpwent(pf)) != NULL) {
- X if (*px->pw_name == '+' || *px->pw_name == '-')
- X continue;
- X if (strcmp(px->pw_name, theUser.pw_name) == 0) {
- X if (strncmp(px->pw_passwd, "##", 2) == 0)
- X quit(0,
- X "Changing of adjunct passwords not supported.\n");
- X islocal++;
- X break;
- X }
- X }
- X rewind(pf);
- X
- X /*
- X * If the user was not in the local password file, use RPC
- X * to update the Yellow Pages (NIS) password file.
- X */
- X if (islocal == 0) {
- X if (is_yp_master() == NOT) {
- X int rc; /* Return code from ypasswdd */
- X int why; /* RPC call return code */
- X int ypport; /* Port for RPC call */
- X struct yppasswd yppasswd; /* YP passwd change block */
- X char salt[4]; /* Password encryption salt */
- X
- X if (curpwd[0] == 0)
- X quit(0, "Cannot change YP password without old password.\n");
- X randomstring(salt, sizeof(salt));
- X theUser.pw_passwd = crypt(newpwd, salt);
- X yppasswd.oldpass = curpwd;
- X _cppasswd(&theUser, &yppasswd.newpw);
- X#ifdef DEBUG
- X printf("yppasswd(%s, %s)\n", curpwd, theUser.pw_passwd);
- X#else
- X if ((ypport = getrpcport(ypmaster, YPPASSWDPROG,
- X YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0)
- X quit(1, "%s is not running ypassswdd.\n",
- X ypmaster);
- X
- X if (ypport >= IPPORT_RESERVED)
- X quit(1, "yppasswdd on %s not privleged.\n",
- X ypmaster);
- X rc = callrpc(ypmaster, YPPASSWDPROG, YPPASSWDVERS,
- X YPPASSWDPROC_UPDATE, xdr_yppasswd, &yppasswd,
- X xdr_int, &why);
- X
- X /* RPC call error */
- X if (rc)
- X#if NO_CLNT_SPERRNO
- X clnt_perrno(rc);
- X quit(1, "Password change failed (%s)\n",
- X ypmaster);
- X#else
- X quit(1, "Password change failed (%s): %s\n",
- X ypmaster, clnt_sperrno(rc));
- X#endif
- X
- X /* Error returned from yppasswdd */
- X if (why) {
- X#ifdef SYSLOG
- X syslog(LOG_ERR,
- X "yppasswdd error %d on %s for %s",
- X why, ypmaster, theUser.pw_name);
- X#endif
- X if (why == 1)
- X quit(0, yperrmsg, ypdomain, ypmaster);
- X else
- X quit(1, "Password change failed.\n");
- X }
- X# ifdef SECURE_RPC
- X reset_secret_key(curpwd);
- X# endif /* SECURE_RPC */
- X#endif /* DEBUG */
- X return;
- X }
- X else /* User not in local passwd, and not in YP passwd */
- X quit(1, "User %s missing from password file.\n",
- X theUser.pw_name);
- X }
- X
- X /*
- X * There is a local password file to change
- X */
- X (void) umask(0);
- X (void) fstat(fileno(pf), &oldstat);
- X /*
- X * Use different temp file if on YP master.
- X * This deals with the SunOS 4.0.3 yppasswdd which creates temp files
- X * named "passwd-file.ptmp", rather than the traditional "/etc/ptmp".
- X * But there are still a lot of applications which use /etc/ptmp,
- X * so is it used as the passwd temp file and the 'auxlockfile' is
- X * also made --- >>>GROAN<<<.
- X */
- X auxlockfile[0] = 0;
- X if (is_yp_master() == IS) {
- X (void) sprintf(auxlockfile, "%s.ptmp", passwdfile);
- X close(mklocktemp(auxlockfile));
- X }
- X mytempfile = 1;
- X fd = mklocktemp(passwdtemp);
- X if ((tf = fdopen(fd, "w")) == NULL)
- X quit(1, "Cannot fdopen temp file.\n");
- X
- X oldsigs = sigblock(blocksigs);
- X while ((px = fgetpwent(pf)) != NULL) {
- X if (px->pw_name == 0 || px->pw_name[0] == 0) /* Sanity check */
- X continue;
- X if (strcmp(px->pw_name, theUser.pw_name) == 0) {
- X char salt[4]; /* Password encryption salt */
- X
- X randomstring(salt, sizeof(salt));
- X theUser.pw_passwd = crypt(newpwd, salt);
- X px = &theUser;
- X }
- X (void) putpwent(px, tf);
- X }
- X (void) fflush(tf); /* Force buffers empty */
- X (void) fstat(fileno(tf), &newstat); /* Get size */
- X (void) fclose(tf);
- X (void) fclose(pf);
- X
- X /*
- X * Check if the new password file is complete. Since the encrypted
- X * password is of a fixed length, the new file should be roughly
- X * the same size as the old one.
- X *
- X * This assumption will FAIL when this program does chfn and chsh!!! -
- X * use line counts.
- X */
- X if (newstat.st_size < (oldstat.st_size - SLOP))
- X quit(1,
- X "New password file appears to be incomplete - aborting.\n");
- X
- X if (rename(passwdfile, savefile) < 0) {
- X perror("Password file save");
- X (void) unlink(passwdtemp);
- X quit(1, "Can't save password file.\n");
- X }
- X if (rename(passwdtemp, passwdfile) < 0) {
- X perror("Password file replace");
- X (void) unlink(passwdtemp);
- X (void) link(savefile, passwdfile);
- X quit(1, "Can't replace password file.\n");
- X }
- X if (is_yp_master() == IS)
- X updateyp();
- X (void) sigsetmask(oldsigs);
- X}
- X
- X/*
- X * pw_cleanup - clean up after myself
- X */
- Xpw_cleanup(code)
- Xint code; /* 0 for normal, 1 for abort */ /*NOTUSED*/
- X{
- X if (mytempfile) {
- X (void) unlink(passwdtemp);
- X if (auxlockfile[0])
- X (void) unlink(auxlockfile);
- X }
- X}
- X
- X/*
- X * _newstr - copy string into new storage
- X */
- Xstatic char *
- X_newstr(s)
- Xchar *s; /* String to copy */
- X{
- X register char *t; /* Temp */
- X char *malloc();
- X
- X if (s == NULL)
- X return(0);
- X t = malloc(strlen(s) + 1);
- X if (t == NULL)
- X quit(1, "No memory.\n");
- X (void) strcpy(t, s);
- X return(t);
- X}
- X
- X/*
- X * mklocktemp - Make temp file with exclusive use checking
- X *
- X * Returns file descriptor of created file, else exits with error
- X */
- Xstatic int
- Xmklocktemp(name)
- Xchar *name;
- X{
- X int fd;
- X
- X fd = open(name, O_WRONLY|O_CREAT|O_EXCL, PASSWD_MODE);
- X if (fd < 0) {
- X if (errno == EEXIST)
- X quit(0, "Password file busy - try again.\n");
- X perror("Tempfile create");
- X quit(1, "Cannot create temp file.\n");
- X }
- X return(fd);
- X}
- X
- X/*
- X * _cppasswd - copy a passwd structure
- X */
- Xstatic
- X_cppasswd(f,t)
- Xpasswdp f, /* From */
- X t; /* To */
- X{
- X *t = *f;
- X t->pw_name = _newstr(f->pw_name);
- X t->pw_passwd = _newstr(f->pw_passwd);
- X t->pw_comment = _newstr(f->pw_comment);
- X t->pw_gecos = _newstr(f->pw_gecos);
- X t->pw_dir = _newstr(f->pw_dir);
- X t->pw_shell = _newstr(f->pw_shell);
- X}
- X
- X/*
- X * is_yp_master - Figure out whether we are running on the Yellow Pages
- X * master for the password file maps.
- X *
- X * Returns:
- X * IS if we are the master
- X * NOT if we are not the master
- X * NONE if there is no master
- X */
- X#include <netdb.h>
- X#ifndef MAXHOSTNAMLEN
- X#define MAXHOSTNAMLEN 32
- X#endif
- X
- Xis_yp_master()
- X{
- X static char known = 0, /* We've been here */
- X answer = NOT; /* ...and this is the answer */
- X char hostname[MAXHOSTNAMLEN]; /* Our host name */
- X char *index();
- X struct hostent *hinfo;
- X
- X if (known)
- X return(answer);
- X (void) gethostname(hostname, sizeof(hostname));
- X if (yp_get_default_domain(&ypdomain)) {
- X/* quit(1, "Cannot get YP domain.\n"); */
- X known++;
- X return(answer = NONE); /* Assume no YP running */
- X }
- X
- X if (yp_master(ypdomain, PASSWD_MAP, &ypmaster)) {
- X known++;
- X return(answer = NONE); /* Assume no YP running */
- X }
- X
- X known++;
- X#ifdef FASTCHECK
- X /*
- X * Stupid (but fast) hostname check (first component only)
- X */
- X {
- X char *p; /* Scratch */
- X
- X if (p = index(ypmaster, '.')) *p = 0;
- X if (p = index(hostname, '.')) *p = 0;
- X }
- X#else
- X /*
- X * Compare my host name and the YP master's host name.
- X * Use gethostbyname() to return the fully qualified form so that
- X * a string compare can be done.
- X */
- X if (index(hostname, '.') == 0) {
- X if ((hinfo = gethostbyname(hostname)) == 0)
- X quit(1, "Cannot get hostinfo for self.\n");
- X (void) strcpy(hostname, hinfo->h_name);
- X }
- X if (index(ypmaster, '.') == 0) {
- X static char ypmaster_f[MAXHOSTNAMLEN];
- X
- X if ((hinfo = gethostbyname(ypmaster)) == 0)
- X quit(1, "Cannot get hostinfo for ypmaster.\n");
- X (void) strcpy(ypmaster_f, hinfo->h_name);
- X ypmaster = ypmaster_f;
- X }
- X#endif
- X if (strcmp(ypmaster, hostname) == 0)
- X return(answer = IS);
- X return(answer);
- X}
- X
- X/*
- X * An example sh(1) script to update YP password map
- X */
- Xchar *ypcmd =
- X "(PATH=/bin:/usr/bin; export PATH; ypdirs='/var/yp /etc/yp'\n\
- X for d in $ypdirs; do\n\
- X if [ -d $d ]; then\n\
- X cd $d; exec make passwd\n\
- X fi\n\
- X done\n\
- X echo 'passwd: Cannot rebuild YP maps!' 1>&2\n\
- X false) >/dev/null &\n";
- X
- X/*
- X * updateyp - update local YP maps
- X */
- Xupdateyp()
- X{
- X (void) setuid(geteuid()); /* Get all privs */
- X /* (This assumes that we are setuid root) */
- X /*
- X * This machine is the YP master for passwd - invoke something
- X * to update the YP maps.
- X * Super-user can override the default YP updater by setting
- X * env "YP_UPDATE_PROC" to a command to be run instead.
- X * The name of the user being changed is piped to stdin of the command.
- X */
- X if (myuid == 0) {
- X char *getenv();
- X char *proc = getenv("YP_UPDATE_PROC");
- X
- X if (proc && *proc) {
- X char cmdbuf[BUFSIZ];
- X
- X (void) sprintf(cmdbuf, "/bin/echo '%s' | ( %s )",
- X theUser.pw_name, proc);
- X#ifdef DEBUG
- X printf("updateyp (proc): %s", cmdbuf);
- X#endif
- X (void) system(cmdbuf);
- X return;
- X }
- X }
- X#ifdef DEBUG
- X printf("updateyp: %s", ypcmd);
- X#endif
- X (void) system(ypcmd);
- X}
- X
- X#ifdef SECURE_RPC
- X/*
- X * reset_secret_key - Reset secret key for secure RPC
- X */
- Xreset_secret_key(curpwd)
- Xchar *curpwd;
- X{
- X char mynet[MAXNETNAMELEN+1],
- X key[HEXKEYBYTES+1];
- X
- X getnetname(mynet);
- X if (!getsecretkey(mynet, key, curpwd))
- X return; /* Secure RPC not running */
- X if (key[0] = 0)
- X return; /* No secret key */
- X fprintf(stderr, "Cannot change secure RPC key\n");
- X /*
- X * Actually I could, but I'd have to steal from Sun source
- X * code to do it. Sun wouldn't like that very much, so I won't.
- X */
- X}
- X#endif
- X/* End pw_yp.c */
- END_OF_FILE
- if test 16110 -ne `wc -c <'pw_yp.c'`; then
- echo shar: \"'pw_yp.c'\" unpacked with wrong size!
- fi
- # end of 'pw_yp.c'
- fi
- echo shar: End of archive 3 \(of 3\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Clyde Hoover (Shouter-To-Dead-Parrots) |
- UNIX/VMS Services | "Any sufficently advanced technology
- Compuatation Center, UT Austin | is indisguishable from a rigged demo."
- clyde@emx.utexas.edu |
-
-